package com.example.zlloggingservice.common.base;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.zlloggingservice.common.util.ConvertHandler;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

/**
 * @Author zhenliu（孙凌岳）
 * @Description AI生成-分页结果包装 (兼容 MyBatis-Plus)
 * @Date 2025/6/17 8:21
 * @Version 1.0
 */
@Data
@ApiModel(value = "分页数据消息体", description = "分页数据统一对象")
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor
public class PageResponse<T> {

    @ApiModelProperty(value = "总条目数", required = true)
    private Long total = 0L;

    @ApiModelProperty(value = "页尺寸", required = true)
    private Integer pageSize = 0;

    @ApiModelProperty(value = "总页数", required = true)
    private Long pages = 0L;

    @ApiModelProperty(value = "页码", required = true)
    private Integer page = 0;

    @ApiModelProperty(value = "数据列表", required = true)
    private List<T> records = Collections.emptyList();

    /**
     * 通过 MyBatis-Plus 的 IPage 对象构造分页响应，不转换 items
     */
    public PageResponse(IPage<?> page) {
        this.page = Convert.toInt(page.getCurrent());
        this.total = page.getTotal();
        this.pageSize = Convert.toInt(page.getSize());
        this.pages = page.getPages();
    }

    /**
     * 通过 MyBatis-Plus 的 IPage 对象构造分页响应，转换 items 为指定类型
     */
    public PageResponse(IPage<?> page, Class<T> clazz) {
        this.page = Convert.toInt(page.getCurrent());
        this.total = page.getTotal();
        this.pageSize = Convert.toInt(page.getSize());
        this.pages = page.getPages();
        this.records = BeanUtil.copyToList(page.getRecords(), clazz);
    }

    /**
     * 返回一个空分页对象实例
     */
    public static <T> PageResponse<T> getInstance() {
        return PageResponse.<T>builder().build();
    }

    /**
     * IPage对象封装为PageResponse，不转换 items
     */
    public static <T> PageResponse<T> of(IPage<?> page) {
        return PageResponse.<T>builder()
                .page(Convert.toInt(page.getCurrent()))
                .pageSize(Convert.toInt(page.getSize()))
                .pages(page.getPages())
                .total(page.getTotal())
                .build();
    }

    /**
     * IPage对象封装为PageResponse，转换 items 为指定类型
     */
    public static <T> PageResponse<T> of(IPage<?> page, Class<T> clazz) {
        return of(page, clazz, null);
    }

    /**
     * IPage对象封装为PageResponse，转换 items 为指定类型，支持自定义转换器
     */
    public static <O, T> PageResponse<T> of(IPage<O> page, Class<T> clazz, ConvertHandler<O, T> convertHandler) {
        return PageResponse.<T>builder()
                .page(Convert.toInt(page.getCurrent()))
                .pageSize(Convert.toInt(page.getSize()))
                .pages(page.getPages())
                .total(page.getTotal())
                .records(copyToList(page.getRecords(), clazz, convertHandler))
                .build();
    }

    /**
     * 对items进行类型转换
     */
    public static <O, T> PageResponse<T> of(PageResponse<O> origin, Class<T> clazz) {
        return of(origin, clazz, null);
    }

    public static <O, T> PageResponse<T> of(PageResponse<O> origin, Class<T> clazz, ConvertHandler<O, T> convertHandler) {
        PageResponse<T> target = PageResponse.getInstance();
        BeanUtil.copyProperties(origin, target, "records");

        if (CollUtil.isEmpty(origin.getRecords())) {
            return target;
        }

        List<T> targetList = copyToList(origin.getRecords(), clazz, convertHandler);
        target.setRecords(targetList);

        return target;
    }

    /**
     * List封装为分页数据对象
     */
    public static <T> PageResponse<T> of(List<T> items, Integer page, Integer pageSize, Long pages, Long total) {
        PageResponse<T> pageResponse = PageResponse.<T>builder()
                .page(Optional.ofNullable(page).orElse(1))
                .pageSize(Optional.ofNullable(pageSize).orElse(1))
                .pages(Optional.ofNullable(pages).orElse(1L))
                .total(Optional.ofNullable(total).orElse(1L))
                .build();

        if (CollUtil.isEmpty(items)) {
            return pageResponse;
        }
        pageResponse.setRecords(items);
        return pageResponse;
    }

    /**
     * List封装为分页数据对象，默认页码相关字段为1
     */
    public static <T> PageResponse<T> of(List<T> items) {
        return of(items, null, null, null, null);
    }

    @SafeVarargs
    public static <E> PageResponse<E> of(E... elements) {
        return of(List.of(elements));
    }

    /**
     * 对items进行类型转换，自定义函数版本
     */
    public static <O, T> PageResponse<T> of(PageResponse<O> origin, Function<List<O>, List<T>> function) {
        List<T> targetList = function.apply(origin.getRecords());
        return PageResponse.of(targetList, origin.getPage(), origin.getPageSize(), origin.getPages(), origin.getTotal());
    }

    /**
     * 通用转换items列表方法，支持自定义转换器
     */
    private static <T, O> List<T> copyToList(List<O> content, Class<T> clazz, ConvertHandler<O, T> convertHandler) {
        List<T> targetList = BeanUtil.copyToList(content, clazz);

        if (CollUtil.isNotEmpty(targetList) && ObjectUtil.isNotEmpty(convertHandler)) {
            for (int i = 0; i < content.size(); i++) {
                convertHandler.map(content.get(i), targetList.get(i));
            }
        }
        return targetList;
    }
}
